WebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒãæ¢æ±ãããŠã§ããã©ãŠã¶å ã§ã®GPGPUããã°ã©ãã³ã°ãšäžŠååŠçãå®çŸããŸããæ±çšèšç®ã«GPUãã¯ãŒã掻çšãããŠã§ãã¢ããªã±ãŒã·ã§ã³ãåäŸã®ãªãããã©ãŒãã³ã¹ã§åŒ·åããæ¹æ³ãåŠã³ãŸãããã
WebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒïŒäžŠååŠçã®ããã®GPGPUãã¯ãŒãè§£æŸ
ãŠã§ããã©ãŠã¶ã§çŸããã°ã©ãã£ãã¯ã¹ãæç»ããããšã§äŒçµ±çã«ç¥ãããŠããWebGLã¯ãåãªãèŠèŠè¡šçŸãè¶ ããŠé²åããŸãããWebGL 2ã«ã³ã³ãã¥ãŒãã·ã§ãŒããŒãå°å ¥ãããããšã§ãéçºè ã¯ã°ã©ãã£ãã¯ã¹ããã»ãã·ã³ã°ãŠãããïŒGPUïŒã®å·šå€§ãªäžŠååŠçèœåãæ±çšèšç®ã«æŽ»çšã§ããããã«ãªããŸãããããã¯GPGPUïŒGeneral-Purpose computing on Graphics Processing UnitsïŒãšããŠç¥ãããæè¡ã§ããããã«ãããèšå€§ãªèšç®ãªãœãŒã¹ãå¿ èŠãšãããŠã§ãã¢ããªã±ãŒã·ã§ã³ãé«éåããããšããµã€ãã£ã³ã°ãªå¯èœæ§ãéãããŸãã
ã³ã³ãã¥ãŒãã·ã§ãŒããŒãšã¯ïŒ
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ãGPUäžã§ä»»æã®èšç®ãå®è¡ããããã«èšèšãããç¹æ®ãªã·ã§ãŒããŒããã°ã©ã ã§ããã°ã©ãã£ãã¯ã¹ãã€ãã©ã€ã³ã«å¯æ¥ã«çµåããŠããé ç¹ã·ã§ãŒããŒããã©ã°ã¡ã³ãã·ã§ãŒããŒãšã¯ç°ãªããã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ç¬ç«ããŠåäœããããã倿°ã®å°ããªç¬ç«ããæäœã«åå²ããŠäžŠåå®è¡ã§ããã¿ã¹ã¯ã«æé©ã§ãã
ãã®ããã«èããŠã¿ãŠãã ããã倧éã®ã«ãŒãã®ãããããœãŒããããšããŸããäžäººããããå šäœãé çªã«ãœãŒããã代ããã«ãå°ããªæãå€ãã®äººã ã«é ãã圌ããåæã«èªåã®æããœãŒãããããšãã§ããŸããã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ãããŒã¿ã«å¯ŸããŠåæ§ã®ããšãå¯èœã«ããçŸä»£ã®GPUã§å©çšå¯èœãªäœçŸãäœåãã®ã³ã¢ã«åŠçã忣ãããŸãã
ãªãã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿ãã®ãïŒ
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšããäž»ãªå©ç¹ã¯ããã©ãŒãã³ã¹ã§ããGPUã¯æ¬è³ªçã«äžŠååŠççšã«èšèšãããŠãããç¹å®ã®ã¿ã€ãã®ã¿ã¹ã¯ã§ã¯CPUãããå€§å¹ ã«é«éã§ããäž»ãªå©ç¹ã以äžã«ç€ºããŸãã
- å€§èŠæš¡ãªäžŠåæ§ïŒ GPUã¯å€æ°ã®ã³ã¢ãææããŠãããäœåãã®ã¹ã¬ãããåæã«å®è¡ã§ããŸããããã¯ãå€ãã®ããŒã¿èŠçŽ ã«å¯ŸããŠåãæäœãå®è¡ããå¿ èŠãããããŒã¿äžŠåèšç®ã«çæ³çã§ãã
- é«ãã¡ã¢ãªåž¯åå¹ ïŒ GPUã¯ãå€§èŠæš¡ãªããŒã¿ã»ããã«å¹ççã«ã¢ã¯ã»ã¹ããŠåŠçããããã«ãé«ãã¡ã¢ãªåž¯åå¹ ã§èšèšãããŠããŸããããã¯ãé »ç¹ãªã¡ã¢ãªã¢ã¯ã»ã¹ãå¿ èŠãšããèšç®éçŽåã®ã¿ã¹ã¯ã«ãšã£ãŠéèŠã§ãã
- è€éãªã¢ã«ãŽãªãºã ã®é«éåïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ãç»ååŠçãç§åŠã·ãã¥ã¬ãŒã·ã§ã³ãæ©æ¢°åŠç¿ãéèã¢ããªã³ã°ãªã©ãããŸããŸãªé åã®ã¢ã«ãŽãªãºã ãå€§å¹ ã«é«éåã§ããŸãã
ç»ååŠçã®äŸãèããŠã¿ãŸããããç»åã«ãã£ã«ã¿ãŒãé©çšããã«ã¯ãåãã¯ã»ã«ã«å¯ŸããŠæ°åŠçãªæäœãå®è¡ããå¿ èŠããããŸããCPUã§ã¯ãããã¯äžåºŠã«1ãã¯ã»ã«ãã€é çªã«ïŒãŸãã¯ãéå®çãªäžŠååŠçã®ããã«è€æ°ã®CPUã³ã¢ã䜿çšããŠïŒè¡ãããŸããã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšãããšãåãã¯ã»ã«ãGPUäžã®å¥ã ã®ã¹ã¬ããã§åŠçã§ãããããåçãªé床åäžãããããããŸãã
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã®ä»çµã¿ïŒç°¡åãªæŠèŠ
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã®äœ¿çšã«ã¯ãããã€ãã®éèŠãªã¹ããããå«ãŸããŸãã
- ã³ã³ãã¥ãŒãã·ã§ãŒããŒïŒGLSLïŒãäœæããïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ãé ç¹ã·ã§ãŒããŒããã©ã°ã¡ã³ãã·ã§ãŒããŒã«äœ¿çšãããã®ãšåãèšèªã§ããGLSLïŒOpenGL Shading LanguageïŒã§èšè¿°ãããŸããã·ã§ãŒããŒå ã§äžŠåå®è¡ãããã¢ã«ãŽãªãºã ãå®çŸ©ããŸããããã«ã¯ãå ¥åããŒã¿ïŒãã¯ã¹ãã£ããããã¡ãªã©ïŒãåºåããŒã¿ïŒãã¯ã¹ãã£ããããã¡ãªã©ïŒãããã³åããŒã¿èŠçŽ ãåŠçããããžãã¯ã®æå®ãå«ãŸããŸãã
- WebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒããã°ã©ã ãäœæããïŒ é ç¹ã·ã§ãŒããŒããã©ã°ã¡ã³ãã·ã§ãŒããŒçšã®ããã°ã©ã ãäœæããã®ãšåæ§ã«ãã³ã³ãã¥ãŒãã·ã§ãŒããŒã®ãœãŒã¹ã³ãŒããã³ã³ãã€ã«ããŠWebGLããã°ã©ã ãªããžã§ã¯ãã«ãªã³ã¯ããŸãã
- ãããã¡/ãã¯ã¹ãã£ãäœæããŠãã€ã³ãããïŒ GPUäžã«ãããã¡ãŸãã¯ãã¯ã¹ãã£ã®åœ¢ã§ã¡ã¢ãªãå²ãåœãŠãå ¥åããã³åºåããŒã¿ãæ ŒçŽããŸããæ¬¡ã«ããããã®ãããã¡/ãã¯ã¹ãã£ãã³ã³ãã¥ãŒãã·ã§ãŒããŒããã°ã©ã ã«ãã€ã³ãããã·ã§ãŒããŒå ã§ã¢ã¯ã»ã¹ã§ããããã«ããŸãã
- ã³ã³ãã¥ãŒãã·ã§ãŒããŒããã£ã¹ãããããïŒ
gl.dispatchCompute()颿°ã䜿çšããŠã³ã³ãã¥ãŒãã·ã§ãŒããŒãèµ·åããŸãããã®é¢æ°ã¯ãå®è¡ãããã¯ãŒã¯ã°ã«ãŒãã®æ°ãæå®ããäºå®äžã䞊ååŠçã®ã¬ãã«ãå®çŸ©ããŸãã - çµæãèªã¿æ»ãïŒä»»æïŒïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒã®å®è¡ãå®äºããåŸããªãã·ã§ã³ã§åºåãããã¡/ãã¯ã¹ãã£ããCPUã«çµæãèªã¿æ»ãããããªãåŠçã衚瀺ãè¡ãããšãã§ããŸãã
ç°¡åãªäŸïŒãã¯ãã«ã®å ç®
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšããŠ2ã€ã®ãã¯ãã«ãå ç®ãããšããåçŽåãããäŸã§ããã®æŠå¿µã説æããŸãããããã®äŸã¯ãäžå¿çãªæŠå¿µã«çŠç¹ãåœãŠãããã«æå³çã«åçŽåãããŠããŸãã
ã³ã³ãã¥ãŒãã·ã§ãŒããŒïŒvector_add.glslïŒïŒ
#version 310 es
layout (local_size_x = 64) in;
layout (std430, binding = 0) buffer InputA {
float a[];
};
layout (std430, binding = 1) buffer InputB {
float b[];
};
layout (std430, binding = 2) buffer Output {
float result[];
};
void main() {
uint index = gl_GlobalInvocationID.x;
result[index] = a[index] + b[index];
}
解説ïŒ
#version 310 esïŒGLSL ES 3.1ããŒãžã§ã³ïŒWebGL 2ïŒãæå®ããŸããlayout (local_size_x = 64) in;ïŒã¯ãŒã¯ã°ã«ãŒãã®ãµã€ãºãå®çŸ©ããŸããåã¯ãŒã¯ã°ã«ãŒãã¯64ã¹ã¬ããã§æ§æãããŸããlayout (std430, binding = 0) buffer InputA { ... };ïŒInputAãšããååã®ã·ã§ãŒããŒã¹ãã¬ãŒãžãããã¡ãªããžã§ã¯ãïŒSSBOïŒã宣èšãããã€ã³ãã£ã³ã°ãã€ã³ã0ã«ãã€ã³ãããŸãããã®ãããã¡ã«ã¯æåã®å ¥åãã¯ãã«ãå«ãŸããŸããstd430ã¬ã€ã¢ãŠãã¯ããã©ãããã©ãŒã éã§äžè²«ããã¡ã¢ãªã¬ã€ã¢ãŠããä¿èšŒããŸããlayout (std430, binding = 1) buffer InputB { ... };ïŒ2çªç®ã®å ¥åãã¯ãã«ïŒInputBïŒçšã«åæ§ã®SSBOã宣èšãããã€ã³ãã£ã³ã°ãã€ã³ã1ã«ãã€ã³ãããŸããlayout (std430, binding = 2) buffer Output { ... };ïŒåºåãã¯ãã«ïŒresultïŒçšã®SSBOã宣èšãããã€ã³ãã£ã³ã°ãã€ã³ã2ã«ãã€ã³ãããŸããuint index = gl_GlobalInvocationID.x;ïŒçŸåšå®è¡ãããŠããã¹ã¬ããã®ã°ããŒãã«ã€ã³ããã¯ã¹ãååŸããŸãããã®ã€ã³ããã¯ã¹ã¯ãå ¥åããã³åºåãã¯ãã«ã®æ£ããèŠçŽ ã«ã¢ã¯ã»ã¹ããããã«äœ¿çšãããŸããresult[index] = a[index] + b[index];ïŒãã¯ãã«ã®å ç®ãå®è¡ããaãšbãã察å¿ããèŠçŽ ãå ããŠãçµæãresultã«æ ŒçŽããŸãã
JavaScriptã³ãŒãïŒæŠå¿µçïŒïŒ
// 1. WebGLã³ã³ããã¹ããäœæïŒcanvasèŠçŽ ããããšä»®å®ïŒ
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl2');
// 2. ã³ã³ãã¥ãŒãã·ã§ãŒããŒãããŒãããŠã³ã³ãã€ã«ïŒvector_add.glslïŒ
const computeShaderSource = await loadShaderSource('vector_add.glsl'); // ã·ã§ãŒããŒãœãŒã¹ãããŒããã颿°ãæ³å®
const computeShader = gl.createShader(gl.COMPUTE_SHADER);
gl.shaderSource(computeShader, computeShaderSource);
gl.compileShader(computeShader);
// ãšã©ãŒãã§ãã¯ïŒç°¡æœãã®ããçç¥ïŒ
// 3. ããã°ã©ã ãäœæããã³ã³ãã¥ãŒãã·ã§ãŒããŒãã¢ã¿ãã
const computeProgram = gl.createProgram();
gl.attachShader(computeProgram, computeShader);
gl.linkProgram(computeProgram);
gl.useProgram(computeProgram);
// 4. ãããã¡ïŒSSBOïŒãäœæããŠãã€ã³ã
const vectorSize = 1024; // ãã¯ãã«ã®ãµã€ãºäŸ
const inputA = new Float32Array(vectorSize);
const inputB = new Float32Array(vectorSize);
const output = new Float32Array(vectorSize);
// inputAãšinputBã«ããŒã¿ãå
¥åïŒç°¡æœãã®ããçç¥ïŒ
const bufferA = gl.createBuffer();
gl.bindBuffer(gl.SHADER_STORAGE_BUFFER, bufferA);
gl.bufferData(gl.SHADER_STORAGE_BUFFER, inputA, gl.STATIC_DRAW);
gl.bindBufferBase(gl.SHADER_STORAGE_BUFFER, 0, bufferA); // ãã€ã³ãã£ã³ã°ãã€ã³ã0ã«ãã€ã³ã
const bufferB = gl.createBuffer();
gl.bindBuffer(gl.SHADER_STORAGE_BUFFER, bufferB);
gl.bufferData(gl.SHADER_STORAGE_BUFFER, inputB, gl.STATIC_DRAW);
gl.bindBufferBase(gl.SHADER_STORAGE_BUFFER, 1, bufferB); // ãã€ã³ãã£ã³ã°ãã€ã³ã1ã«ãã€ã³ã
const bufferOutput = gl.createBuffer();
gl.bindBuffer(gl.SHADER_STORAGE_BUFFER, bufferOutput);
gl.bufferData(gl.SHADER_STORAGE_BUFFER, output, gl.STATIC_DRAW);
gl.bindBufferBase(gl.SHADER_STORAGE_BUFFER, 2, bufferOutput); // ãã€ã³ãã£ã³ã°ãã€ã³ã2ã«ãã€ã³ã
// 5. ã³ã³ãã¥ãŒãã·ã§ãŒããŒããã£ã¹ããã
const workgroupSize = 64; // ã·ã§ãŒããŒã®local_size_xãšäžèŽãããå¿
èŠããã
const numWorkgroups = Math.ceil(vectorSize / workgroupSize);
gl.dispatchCompute(numWorkgroups, 1, 1);
// 6. ã¡ã¢ãªããªã¢ïŒçµæãèªã¿åãåã«ã³ã³ãã¥ãŒãã·ã§ãŒããŒãçµäºããããšãä¿èšŒïŒ
gl.memoryBarrier(gl.SHADER_STORAGE_BARRIER_BIT);
// 7. çµæãèªã¿æ»ã
gl.bindBuffer(gl.SHADER_STORAGE_BUFFER, bufferOutput);
gl.getBufferSubData(gl.SHADER_STORAGE_BUFFER, 0, output);
// 'output' ã«ã¯ãã¯ãã«ã®å ç®çµæãå«ãŸãã
console.log(output);
解説ïŒ
- JavaScriptã³ãŒãã¯ãŸãWebGL2ã³ã³ããã¹ããäœæããŸãã
- 次ã«ãã³ã³ãã¥ãŒãã·ã§ãŒããŒã®ã³ãŒããããŒãããŠã³ã³ãã€ã«ããŸãã
- å ¥åããã³åºåãã¯ãã«ãä¿æããããã®ãããã¡ïŒSSBOïŒãäœæãããŸããå ¥åãã¯ãã«ã®ããŒã¿ãå ¥åãããŸãïŒãã®ã¹ãããã¯ç°¡æœãã®ããçç¥ãããŠããŸãïŒã
gl.dispatchCompute()颿°ãã³ã³ãã¥ãŒãã·ã§ãŒããŒãèµ·åããŸããã¯ãŒã¯ã°ã«ãŒãã®æ°ã¯ããã¯ãã«ã®ãµã€ãºãšã·ã§ãŒããŒã§å®çŸ©ãããã¯ãŒã¯ã°ã«ãŒãã®ãµã€ãºã«åºã¥ããŠèšç®ãããŸããgl.memoryBarrier()ã¯ãçµæãèªã¿æ»ãããåã«ã³ã³ãã¥ãŒãã·ã§ãŒããŒãå®è¡ãå®äºããããšãä¿èšŒããŸããããã¯ç«¶åç¶æ ãé¿ããããã«éèŠã§ãã- æåŸã«ã
gl.getBufferSubData()ã䜿çšããŠåºåãããã¡ããçµæãèªã¿æ»ãããŸãã
ããã¯éåžžã«åºæ¬çãªäŸã§ãããWebGLã§ã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšããéã®äžå¿çãªååã瀺ããŠããŸããéèŠãªç¹ã¯ãGPUããã¯ãã«ã®å ç®ã䞊åã§å®è¡ããŠããã倧ããªãã¯ãã«ã«å¯ŸããŠã¯CPUããŒã¹ã®å®è£ ãããå€§å¹ ã«é«éã§ãããšããããšã§ãã
WebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒã®å®çšçãªå¿çš
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ãå¹ åºãåé¡ã«å¿çšå¯èœã§ãã以äžã«ããã€ãã®æ³šç®ãã¹ãäŸãæããŸãã
- ç»ååŠçïŒ ãã£ã«ã¿ãŒã®é©çšãç»åè§£æãé«åºŠãªç»åæäœæè¡ã®å®è£ ãäŸãã°ããŒãããã·ã£ãŒãåããšããžæ€åºãè²è£æ£ãªã©ãå€§å¹ ã«é«éåã§ããŸããã³ã³ãã¥ãŒãã·ã§ãŒããŒã®åã®ãããã§ãè€éãªãã£ã«ã¿ãŒããªã¢ã«ã¿ã€ã ã§é©çšã§ãããŠã§ãããŒã¹ã®åçç·šéãœãããæ³åããŠã¿ãŠãã ããã
- ç©çã·ãã¥ã¬ãŒã·ã§ã³ïŒ ããŒãã£ã¯ã«ã·ã¹ãã ãæµäœååŠããã®ä»ã®ç©çããŒã¹ã®çŸè±¡ã®ã·ãã¥ã¬ãŒã·ã§ã³ãããã¯ããªã¢ã«ãªã¢ãã¡ãŒã·ã§ã³ãã€ã³ã¿ã©ã¯ãã£ããªäœéšãäœæããã®ã«ç¹ã«åœ¹ç«ã¡ãŸããã³ã³ãã¥ãŒãã·ã§ãŒããŒé§åã®æµäœã·ãã¥ã¬ãŒã·ã§ã³ã«ãããæ°Žããªã¢ã«ã«æµãããŠã§ãããŒã¹ã®ã²ãŒã ãèããŠã¿ãŠãã ããã
- æ©æ¢°åŠç¿ïŒ æ©æ¢°åŠç¿ã¢ãã«ãç¹ã«ãã£ãŒããã¥ãŒã©ã«ãããã¯ãŒã¯ã®ãã¬ãŒãã³ã°ãšãããã€ãGPUã¯ãè¡åã®ä¹ç®ããã®ä»ã®ç·åœ¢ä»£æ°æŒç®ãå¹ççã«å®è¡ããèœåãããæ©æ¢°åŠç¿ã§åºã䜿çšãããŠããŸãããŠã§ãããŒã¹ã®æ©æ¢°åŠç¿ãã¢ã¯ãã³ã³ãã¥ãŒãã·ã§ãŒããŒãæäŸããé床åäžããæ©æµãåããããšãã§ããŸãã
- ç§åŠæè¡èšç®ïŒ æ°å€ã·ãã¥ã¬ãŒã·ã§ã³ãããŒã¿åæããã®ä»ã®ç§åŠæè¡èšç®ã®å®è¡ãããã«ã¯ãèšç®æµäœååŠïŒCFDïŒãåååååŠãæ°åã¢ããªã³ã°ãªã©ã®åéãå«ãŸããŸããç ç©¶è ã¯ãã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšããŠå€§èŠæš¡ãªããŒã¿ã»ãããèŠèŠåããåæãããŠã§ãããŒã¹ã®ããŒã«ã掻çšã§ããŸãã
- éèã¢ããªã³ã°ïŒ ãªãã·ã§ã³äŸ¡æ Œèšå®ããªã¹ã¯ç®¡çãªã©ã®éèèšç®ã®é«éåãèšç®éçŽåã§ããã¢ã³ãã«ã«ãã·ãã¥ã¬ãŒã·ã§ã³ã¯ãã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšããããšã§å€§å¹ ã«é«éåã§ããŸããéèã¢ããªã¹ãã¯ãã³ã³ãã¥ãŒãã·ã§ãŒããŒã®ãããã§ãªã¢ã«ã¿ã€ã ã®ãªã¹ã¯åæãæäŸãããŠã§ãããŒã¹ã®ããã·ã¥ããŒãã䜿çšã§ããŸãã
- ã¬ã€ãã¬ãŒã·ã³ã°ïŒ äŒçµ±çã«å°çšã®ã¬ã€ãã¬ãŒã·ã³ã°ããŒããŠã§ã¢ã䜿çšããŠå®è¡ãããŸãããããåçŽãªã¬ã€ãã¬ãŒã·ã³ã°ã¢ã«ãŽãªãºã ã¯ãã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšããŠå®è£ ãããŠã§ããã©ãŠã¶ã§ã€ã³ã¿ã©ã¯ãã£ããªã¬ã³ããªã³ã°é床ãéæããããšãã§ããŸãã
å¹ççãªã³ã³ãã¥ãŒãã·ã§ãŒããŒãäœæããããã®ãã¹ããã©ã¯ãã£ã¹
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã®ããã©ãŒãã³ã¹äžã®å©ç¹ãæå€§åããããã«ã¯ãããã€ãã®ãã¹ããã©ã¯ãã£ã¹ã«åŸãããšãéèŠã§ãã
- 䞊ååŠçãæå€§åããïŒ GPUåºæã®äžŠåæ§ã掻çšããããã«ã¢ã«ãŽãªãºã ãèšèšããŸããã¿ã¹ã¯ããåæã«å®è¡ã§ããå°ããªç¬ç«ããæäœã«åå²ããŸãã
- ã¡ã¢ãªã¢ã¯ã»ã¹ãæé©åããïŒ ã¡ã¢ãªã¢ã¯ã»ã¹ãæå°éã«æããããŒã¿ã®å±ææ§ãæå€§åããŸããã¡ã¢ãªã¢ã¯ã»ã¹ã¯ãç®è¡èšç®ã«æ¯ã¹ãŠæ¯èŒçé ãæäœã§ããããŒã¿ãã§ããã ãGPUã®ãã£ãã·ã¥ã«ä¿æããããã«ããŠãã ããã
- å
±æããŒã«ã«ã¡ã¢ãªã䜿çšããïŒ ã¯ãŒã¯ã°ã«ãŒãå
ã§ã¯ãã¹ã¬ããã¯å
±æããŒã«ã«ã¡ã¢ãªïŒGLSLã®
sharedããŒã¯ãŒãïŒãä»ããŠããŒã¿ãå ±æã§ããŸããããã¯ã°ããŒãã«ã¡ã¢ãªã«ã¢ã¯ã»ã¹ãããããã¯ããã«é«éã§ããã°ããŒãã«ã¡ã¢ãªã¢ã¯ã»ã¹ã®åæ°ãæžããããã«ãå ±æããŒã«ã«ã¡ã¢ãªã䜿çšããŸãã - åå²ãæå°éã«æããïŒ åå²ã¯ãã¯ãŒã¯ã°ã«ãŒãå ã®ã¹ã¬ãããç°ãªãå®è¡ãã¹ããã©ãïŒäŸãã°ãæ¡ä»¶æã«ããïŒãšãã«çºçããŸããåå²ã¯ããã©ãŒãã³ã¹ãå€§å¹ ã«äœäžãããå¯èœæ§ããããŸããåå²ãæå°éã«æããã³ãŒããæžãããã«ããŠãã ããã
- é©åãªã¯ãŒã¯ã°ã«ãŒããµã€ãºãéžæããïŒ ã¯ãŒã¯ã°ã«ãŒãã®ãµã€ãºïŒ
local_size_xãlocal_size_yãlocal_size_zïŒã¯ãã°ã«ãŒããšããŠäžç·ã«å®è¡ãããã¹ã¬ããã®æ°ã決å®ããŸããé©åãªã¯ãŒã¯ã°ã«ãŒããµã€ãºãéžæããããšã¯ãããã©ãŒãã³ã¹ã«å€§ããªåœ±é¿ãäžããå¯èœæ§ããããŸããç¹å®ã®ã¢ããªã±ãŒã·ã§ã³ãšããŒããŠã§ã¢ã«æé©ãªå€ãèŠã€ããããã«ãããŸããŸãªã¯ãŒã¯ã°ã«ãŒããµã€ãºã§å®éšããŠãã ãããäžè¬çãªåºçºç¹ã¯ãGPUã®ã¯ãŒããµã€ãºïŒéåžžã¯32ãŸãã¯64ïŒã®åæ°ã§ããã¯ãŒã¯ã°ã«ãŒããµã€ãºã§ãã - é©åãªããŒã¿åã䜿çšããïŒ èšç®ã«ååãªæå°ã®ããŒã¿åã䜿çšããŸããäŸãã°ã32ãããæµ®åå°æ°ç¹æ°ã®å®å
šãªç²ŸåºŠãå¿
èŠãªãå Žåã¯ã16ãããæµ®åå°æ°ç¹æ°ïŒGLSLã®
halfïŒã®äœ¿çšãæ€èšããŠãã ãããããã«ãããã¡ã¢ãªäœ¿çšéãåæžããããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã - ãããã¡ã€ã«ãšæé©åïŒ ãããã¡ã€ãªã³ã°ããŒã«ã䜿çšããŠãã³ã³ãã¥ãŒãã·ã§ãŒããŒã®ããã©ãŒãã³ã¹ããã«ããã¯ãç¹å®ããŸããããŸããŸãªæé©åææ³ã詊ããããã©ãŒãã³ã¹ãžã®åœ±é¿ã枬å®ããŸãã
課é¡ãšèæ ®äºé
ã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯å€§ããªå©ç¹ãæäŸããŸãããçæãã¹ãããã€ãã®èª²é¡ãšèæ ®äºé ããããŸãã
- è€éãïŒ å¹ççãªã³ã³ãã¥ãŒãã·ã§ãŒããŒãæžãããšã¯é£ãããGPUã¢ãŒããã¯ãã£ãšäžŠåããã°ã©ãã³ã°æè¡ã®ååãªçè§£ãå¿ èŠã§ãã
- ãããã°ïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒã®ãããã°ã¯ã䞊åã³ãŒãã®ãšã©ãŒã远跡ããã®ãé£ãããããå°é£ãªå ŽåããããŸããå€ãã®å Žåãå°éã®ãããã°ããŒã«ãå¿ èŠã§ãã
- ç§»æ€æ§ïŒ WebGLã¯ã¯ãã¹ãã©ãããã©ãŒã åãã«èšèšãããŠããŸãããããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ã®ããGPUããŒããŠã§ã¢ããã©ã€ãã®å®è£ ã«ã¯äŸç¶ãšããŠã°ãã€ãããããŸããäžè²«ããããã©ãŒãã³ã¹ã確ä¿ããããã«ãããŸããŸãªãã©ãããã©ãŒã ã§ã³ã³ãã¥ãŒãã·ã§ãŒããŒããã¹ãããŠãã ããã
- ã»ãã¥ãªãã£ïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒã䜿çšããéã¯ãã»ãã¥ãªãã£ã®è匱æ§ã«æ³šæããŠãã ãããæªæã®ããã³ãŒããã·ã§ãŒããŒã«æ³šå ¥ãããã·ã¹ãã ãå±éºã«ãããå¯èœæ§ããããŸããå ¥åããŒã¿ãæ éã«æ€èšŒããä¿¡é Œã§ããªãã³ãŒãã®å®è¡ãé¿ããŠãã ããã
- Web Assembly (WASM) ãšã®çµ±åïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯åŒ·åã§ãããGLSLã§èšè¿°ãããŠããŸããWASMãä»ããŠC++ãªã©ããŠã§ãéçºã§ãã䜿çšãããä»ã®èšèªãšçµ±åããããšã¯è€éã«ãªãå¯èœæ§ããããŸããWASMãšã³ã³ãã¥ãŒãã·ã§ãŒããŒã®éã®ã®ã£ãããåããã«ã¯ãæ éãªããŒã¿ç®¡çãšåæãå¿ èŠã§ãã
WebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒã®æªæ¥
WebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ãGPGPUããã°ã©ãã³ã°ã®åããŠã§ããã©ãŠã¶ã«ããããããŠã§ãéçºã«ããã倧ããªåé²ã衚ããŠããŸãããŠã§ãã¢ããªã±ãŒã·ã§ã³ããŸããŸãè€éã§èŠæ±ãå³ãããªãã«ã€ããŠãã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ããã©ãŒãã³ã¹ãå éãããæ°ããªå¯èœæ§ãå¯èœã«ããäžã§ãŸããŸãéèŠãªåœ¹å²ãæããã§ããããã³ã³ãã¥ãŒãã·ã§ãŒããŒæè¡ã®ãããªã鲿©ãæåŸ ãããŸããããã«ã¯ä»¥äžãå«ãŸããŸãã
- ããŒã«ã®æ¹åïŒ ããåªãããããã°ããã³ãããã¡ã€ãªã³ã°ããŒã«ã«ãããã³ã³ãã¥ãŒãã·ã§ãŒããŒã®éçºãšæé©åã容æã«ãªããŸãã
- æšæºåïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒAPIã®ãããªãæšæºåã«ãããç§»æ€æ§ãåäžãããã©ãããã©ãŒã åºæã®ã³ãŒãã®å¿ èŠæ§ãæžå°ããŸãã
- æ©æ¢°åŠç¿ãã¬ãŒã ã¯ãŒã¯ãšã®çµ±åïŒ æ©æ¢°åŠç¿ãã¬ãŒã ã¯ãŒã¯ãšã®ã·ãŒã ã¬ã¹ãªçµ±åã«ããããŠã§ãã¢ããªã±ãŒã·ã§ã³ã§ã®æ©æ¢°åŠç¿ã¢ãã«ã®ãããã€ã容æã«ãªããŸãã
- æ¡çšã®å¢å ïŒ ã³ã³ãã¥ãŒãã·ã§ãŒããŒã®å©ç¹ãèªèããéçºè ãå¢ããã«ã€ããŠãå¹ åºãã¢ããªã±ãŒã·ã§ã³ã§ã®æ¡çšãå¢å ããããšãæåŸ ãããŸãã
- WebGPUïŒ WebGPUã¯ãWebGLã«ä»£ããããã¢ãã³ã§å¹ççãªæ°ãããŠã§ãã°ã©ãã£ãã¯ã¹APIã§ããWebGPUãã³ã³ãã¥ãŒãã·ã§ãŒããŒããµããŒãããããã«åªããããã©ãŒãã³ã¹ãšæè»æ§ãæäŸããå¯èœæ§ããããŸãã
çµè«
WebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ããŠã§ããã©ãŠã¶å ã§GPUã®äžŠååŠçèœåãè§£ãæŸã€ããã®åŒ·åãªããŒã«ã§ããã³ã³ãã¥ãŒãã·ã§ãŒããŒã掻çšããããšã§ãéçºè ã¯èšç®éçŽåã®ã¿ã¹ã¯ãé«éåãããŠã§ãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãåäžãããæ°ãã驿°çãªäœéšãåµé ããããšãã§ããŸããå æãã¹ã課é¡ã¯ãããŸãããæœåšçãªå©ç¹ã¯å€§ãããã³ã³ãã¥ãŒãã·ã§ãŒããŒã¯ãŠã§ãéçºè ãæ¢æ±ããã®ã«ãšããµã€ãã£ã³ã°ãªåéã§ãã
ãŠã§ãããŒã¹ã®ç»åç·šéãœãããç©çã·ãã¥ã¬ãŒã·ã§ã³ãæ©æ¢°åŠç¿ã¢ããªã±ãŒã·ã§ã³ããŸãã¯ãã®ä»ã®èšå€§ãªèšç®ãªãœãŒã¹ãå¿ èŠãšããã¢ããªã±ãŒã·ã§ã³ãéçºããŠããå Žåã§ããWebGLã³ã³ãã¥ãŒãã·ã§ãŒããŒã®åãæ¢æ±ããããšãæ€èšããŠãã ãããGPUã®äžŠååŠçèœåãæŽ»çšããèœåã¯ãããã©ãŒãã³ã¹ãåçã«åäžããããŠã§ãã¢ããªã±ãŒã·ã§ã³ã®æ°ããªå¯èœæ§ãéãããšãã§ããŸãã
æåŸã®èå¯ãšããŠãã³ã³ãã¥ãŒãã·ã§ãŒããŒã®æè¯ã®äœ¿ãæ¹ã¯ãå¿ ãããçã®é床ã ãã§ã¯ãªãããšãèŠããŠãããŠãã ãããããã¯ãä»äºã«é©ãã*æ£ãã*ããŒã«ãèŠã€ããããšã§ããã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ããã«ããã¯ãæ³šææ·±ãåæããã³ã³ãã¥ãŒãã·ã§ãŒããŒã®äžŠååŠçèœåã倧ããªå©ç¹ãæäŸã§ãããã©ããã倿ããŠãã ãããå®éšãããããã¡ã€ã«ããå埩ããŠãç¹å®ã®ããŒãºã«æé©ãªãœãªã¥ãŒã·ã§ã³ãèŠã€ããŠãã ããã